Projekt Pronal Projekt Pronal

Kazalo:
Sofinasiranje projekta
Starejši - učbenik...
Starejši - zbirka nalog...
Tekmovanja...
Tekmovanja - dopolni...
Tekmovanja - popravi...
Tekmovanja - Parsons
rtk 1988
rtk 1996
rtk 1998
rtk 1999
rtk 2000
rtk 2001
rtk 2002
rtk 2004
rtk 2006
rtk 2007
rtk 2008
rtk 2009
rtk 2014
rtk 2016
rtk 2017
rtk 2018
rtk 2018

rtk 2018


2018.1.2 - zamenjaj vrstice

1. podnaloga

Palček Godrnjavček je postal vodja tajne službe, ki skrbi za varnost Sneguljčice, njegova naloga pa je, da sprejema podatke agentov na terenu in jim daje navodila, kako naj ukrepajo. Da bi se palčki zaščitili pred napakami pri sporazumevanju, so uvedli fonetično abecedo, ki posamezni črki priredi besedo.

A...ALFA          J...JULIET        R...ROMEO
B...BRAVO         K...KILO          S...SIERRA
C...CHARLIE       L...LIMA          T...TANGO
D...DELTA         M...MIKE          U...UNIFORM
E...ECHO          N...NOVEMBER      V...VICTOR
F...FOXTROT       O...OSCAR         W...WHISKY
G...GOLF          P...PAPA          X...X-RAY
H...HOTEL         Q...QUEBEC        Y...YANKEE
I...INDIA                           Z...ZULU

Godrnjavček je napisal funkcijo, ki zna vneseno besedilo dekodirati. Kot vhod torej dobi datoteko s seznamom kodnih besed iz gornje tabele (vsaka v svoji vrstici), vrne pa pripadajoče zaporedje črk.

Pri tem je odporna tudi na manjše napake pri kodiranju: namesto prave kodne besede se lahko v vhodnih podatkih pojavi taka beseda, ki se od prave razlikuje v največ enem znaku (je pa zagotovo še vedno enako dolga kot prava kodna beseda).

Tako se lahko na primer zgodi, da namesto besede LIMA dobimo RIMA ali LINA ali LQMA in tako naprej, vse te besede pa ravno tako predstavljajo črko L.

Na žalost pa je zlobna kraljica uporabila urok, ki je Godrnjavčkovu funkciji premešal vrstice.

def se_ujema(beseda, koda):
if st_neujemanj > 1:
if len(koda) != dolzina_besede:
for i in range(dolzina_besede):
return True
if beseda[i] == koda[i]:
st_neujemanj += 1
continue
st_neujemanj = 0
dolzina_besede = len(beseda)

def dekodiraj(dat):
break
if se_ujema(beseda, kode[znak]):
for vrstica in sporocilo:
for beseda in vrstica.split():
for znak in range(len(kode)):
dekodirana_beseda = ''
return dekodirana_beseda
sporocilo.close()
dekodirana_beseda += (chr(ord('A') + znak))
sporocilo = open(dat,'r',encoding='utf-8')

Naloga

Zamenjaj vrstice v funkcijah dekodiraj(dat) ki sprejme tekstovno datoteko in vrne niz z dekodiranim sporočilom in se_ujema(beseda,koda), ki preveri, s katero črko se ujema koda. Dodaj še dokumentacijo in komentarje!

Vhodni podatki

Tekstovna datoteka z zakodiranim sporočilom z napakami:

SIERRA
RODEO
ERHO
CHARLIF
MOVEMBER
OSQAR

Izhodni podatki

Niz z dekodiranim sporočilom

"SRECNO"

Komentar

Na tekmovanju je bilo možno izbirati med branjem s standardnega vhoda in branjem z datoteke.

Uradna rešitev

kode = ["ALFA", "BRAVO", "CHARLIE" , "DELTA", "ECHO","FOXTROT","GOLF","HOTEL","INDIA","JULIET",
        "KILO","LIMA","MIKE","NOVEMBER","OSCAR","PAPA","QUEBEC","ROMEO","SIERRA","TANGO","UNIFORM",
        "VICTOR","WHISKY","X-RAY","YANKEE","ZULU"]
def se_ujema(beseda, koda):
    '''Funkcija preveri, ali se dana beseda ujema s kodo (z največ 1 napako)
     in vrne True ali False'''
    dolzina_besede = len(beseda)
    st_neujemanj = 0
    if len(koda) != dolzina_besede:
        return False
    for i in range(dolzina_besede):
        if beseda[i] == koda[i]:
            continue
        st_neujemanj += 1
        if st_neujemanj > 1:
            return False
    return True

def dekodiraj(dat):
    '''Funkcija pretvori zakodirano sporočilo v datoteki v nam razumljivo,
       jo shrani v niz in vrne.'''
    dekodirana_beseda = ''
    sporocilo = open(dat,'r',encoding='utf-8')
    for vrstica in sporocilo:
        for beseda in vrstica.split():
            for znak in range(len(kode)):
                if se_ujema(beseda, kode[znak]):
                    dekodirana_beseda += (chr(ord('A') + znak))
                    break
    sporocilo.close()
    return dekodirana_beseda

2018.1.3 - zamenjaj vrstice

Sestavljanka

1. podnaloga

Gojmir je na polici opazil škatlo s sestavljanko, ki ima $136$ koščkov. Gojmir ve, da sestavljanko dobimo tako, da sliko razrežemo s (skoraj) vodoravnimi in (skoraj) navpičnimi črtami, tako da dobimo (skoraj) kvadratne koščke. Opazil pa je, da slika, ki jo tvori sestavljanka, v resnici ni kvadratna. Takole čez palec je ocenil, da je razmerje med višino in širino slike približno $3 : 7$.

Koliko koščkov v resnici pride po višini in koliko po širini? Pravokotnik iz $136$ koščkov bi lahko bil oblike $1×136$ ali $2×68$ ali $4×34$ ali $8×17$ in tako naprej.

Vprašanje je torej, pri katerem od teh pravokotnikov je razmerje med višino in širino najbližje tistemu, ki ga je ocenil Gojmir.

Gojmir je že napisal funkcijo, ki to naredi v splošnem, vendar so se ob prenosu zamenjale vrstice kode.

def sestavljanka(st_kosov, razmerje):
if st_kosov % h != 0:
if h == 1 or razlika < min_razlika:
return (naj_visina, st_kosov // naj_visina)
razlika = abs(h / priblizek - razmerje)
naj_visina = h
continue
for h in range(1, st_kosov + 1):
priblizek = st_kosov // h
min_razlika = razlika

Naloga

Zamenjaj vrstice v funkciji sestavljanka(st_kosov, razmerje), ki bo to izračunala v splošnem primeru, za poljubno število koščkov in poljubno razmerje. Gojmir določi razmerje višine in širine dokaj natančno, vendar ne povsem natančno.

Vhodni podatki

Parametra funkcije sta število koščkov (naravno število) in razmerje (realno število)

>>> sestavljanka(136, 0.428)

$(3/7 ≈ 0.428)$

Izhodni podatki

Funkcija mora vrniti par

(8 , 17)

(8 vrstic, 17 stolpcev). Pri tej sestavljanki je razmerje med višino in širino enako $8/17 ≈ 0,471$, kar je od vseh možnih pravokotnih sestavljank s $136$ koščki najbližje iskanemu razmerju $0,428.

Uradna rešitev

def sestavljanka(st_kosov, razmerje):
    '''Izračuna in vrne tisti približek za razmerje višina:širina,
    ki je najbljižje razmerju '''
    for h in range(1, st_kosov + 1):
        if st_kosov % h != 0:
            continue
        priblizek = st_kosov // h
        razlika = abs(h / priblizek - razmerje)
        if h == 1 or razlika < min_razlika:
            naj_visina = h
            min_razlika = razlika
    return (naj_visina, st_kosov // naj_visina)

2018.1.5 - zamenjaj vrstice

Brzinomer

1. podnaloga

V avtomobilu za prikaz trenutne hitrosti vozila skrbi instrument (brzinomer), ki je lahko digitalen (prikazuje številke) ali pa analogen (fizični kazalec instrumenta se pomika po skali in s svojo lego kaže izmerjeno hitrost).

A tudi prikazovalniki s kazalcem in skalo so doživeli svojo prenovo in niso več preprosti analogni merilniki neke fizikalne veličine, ampak gre za prikazovalnike, kjer je kazalec pritrjen na os miniaturnega koračnega elektromotorčka, pomike tega pa krmili avtomobilski računalnik glede na hitrost, ki jo izmerijo tipala hitrosti.

Naš prikazovalnik ima skalo v obsegu od $0 km/h$ do $250 km/h$. Koračni motorček lahko pomika kazalec v vsakem koraku le za $1 km/h$ navzgor ali navzdol, ali pa kazalca ne premakne. Če je kazalec že v najnižji legi, ukaz za pomik navzdol ne stori ničesar (kazalec ostane v najnižji legi, t.j. kaže na $0 km/h$ na skali). Podobno tudi pri najvišji legi: ukaz za pomik navzgor ne stori ničesar, kazalec ostane pri najvišji legi, t.j. kaže na $250 km/h$ na skali.

Premik koračnega motorčka za en korak (oz. kazalca, pritrjenega nanj, za $1 km/h$) je sicer precej hiter, vendar vseeno zahteva določen čas. Da ne bi avtomobilski računalnik skušal premikati kazalca hitreje, kot to koračni motorček zmore, skrbi ura, ki se proži nekajkrat v sekundi in jamči, da je takrat koračni motorček pripravljen sprejeti nov ukaz za pomik za en korak.

Naloga

kazalec = 0
zacetek = Max
def Premik(hitrost):
    '''Premakne kazalec za 1 naprej, če je hitrost povečana in nazaj
        če je zmanjšana.'''

    hitrost = Max
    zacetek -= 1
    return -1
    if hitrost > Max:
    global kazalec, zacetek
    else:
    premik = 1
    if zacetek > 0:
    premik = -1
    elif hitrost < kazalec:
    premik = 0
    if hitrost > kazalec:
    return premik
    kazalec += premik

Zamenjaj vrstice v funkciji premik(hitrost) (tako, da bo delovala), ki jo bo ura periodično klicala (približno stokrat v sekundi, točna vrednost intervala ni pomembna). Kot argument bo funkcija ob vsakem klicu prejela celo število med $0$ in $300$, ki predstavlja trenutno hitrost avtomobila v $km/h$.

Glede na svoje vedenje o trenutni legi kazalca brzinomera naj funkcija vrne vrednost $−1$, $+1$ ali $0$, kar bo povzročilo pomik kazalca za en korak navzdol ali navzgor ali pa pomika v tem časovnem intervalu ne bo. Funkcija naj skrbi, da bo lega kazalca brzinomera čim bolj verno sledila dejanski hitrosti avtomobila.

Upoštevaj, da se lahko hitrost avtomobila med dvema zaporednima klicema tvoje funkcije spremeni tudi za več kot $1 km/h$. V tem primeru bo sicer kazalec merilnika lahko za krajši čas zaostajal s pravim prikazom, a mora pravo lego po najboljših močeh čim prej ujeti. Pri hitrostih nad prikazovalnim območjem (t.j. nad $250 km/h$) naj kazalec tiči v svoji najvišji legi. Po potrebi lahko deklariraš poljubne globalne spremenljivke in jim tudi določiš začetne vrednosti.

Upoštevaj tudi, da ob zagonu avtomobilskega računalnika ne vemo točno, kje je obtičal kazalec brzinomera — lahko bi se npr. zgodilo, da je bil motor avtomobila (in računalnik) ugasnjen, še preden se je avtomobil dokončno ustavil na domačem dvorišču. Da zagotovimo znano lego kazalca, si lahko pomagamo z informacijo iz drugega odstavka, ki zagotovi, da z $250$ koraki navzdol zagotovo dosežemo spodnjo lego (torej prikaz $0 km/h$) ne glede na začetni položaj kazalca. Za pravilno testiranje zato uporabi

for i in range(251):
    premik(250)

ko napišeš funkcijo.

Uradna rešitev

Max = 250
kazalec = 0
zacetek = Max
def premik(hitrost):
    '''Premakne kazalec za 1 naprej, če je hitrost povečana in nazaj
       če je zmanjšana.'''
    global kazalec, zacetek
    if zacetek > 0:
        zacetek -= 1
        return -1
    if hitrost < 0:
        hitrost = 0
    if hitrost > Max:
        hitrost = Max
    if hitrost > kazalec:
        premik = 1
    elif hitrost < kazalec:
        premik = -1
    else:
        premik = 0
    kazalec += premik
    return premik
Mesto objave ob koncu projekta 15.9.2018